package com.wxapp.pay.service.pay.alipay;

import com.wxapp.common.core.filter.except.ThrowMyException;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.pay.api.pojo.enums.listener.PayStatusEnum;
import com.wxapp.pay.api.pojo.enums.listener.RedirectTypeEnum;
import com.wxapp.pay.api.pojo.pojo.vm.pay.PAliPayVm;
import com.wxapp.pay.api.pojo.pojo.vm.pay.PPayVm;
import com.wxapp.pay.api.pojo.pojo.vm.payConfig.PAliPayConfigsVm;
import com.wxapp.pay.api.pojo.pojo.vo.order.QOrderInfoVo;
import com.wxapp.pay.api.pojo.pojo.vo.payLogs.QPayLogsAddVo;
import com.wxapp.pay.service.pay.BasePay;
import org.springframework.context.ApplicationEvent;

/**
 * @author lgl
 */
public abstract class BaseAliPay extends BasePay {
    /**
     * 获取数据库配置
     */
    protected abstract PAliPayConfigsVm getConfigs() throws ThrowMyException;

    /**
     * 获取请求参数
     */
    protected abstract PAliPayVm getRequestVm(PAliPayConfigsVm config, QOrderInfoVo vo) throws Exception;

    /**
     * 处理请求和代码
     */
    protected abstract PPayVm<String> dealResponseVm(PAliPayConfigsVm config, PAliPayVm vm) throws ThrowMyException;

    /**
     * 发布事件
     */
    protected abstract void publicEvent(QPayLogsAddVo vo, ApplicationEvent... event);

    /**
     * 检查结果
     */
    protected abstract Boolean checkResponse(PPayVm<String> vm, PAliPayVm vp);

    /**
     * 检查结果
     * 包括失败重试
     */
    protected abstract Boolean redirect(QOrderInfoVo vo);


    @Override
    protected String invoke(QOrderInfoVo vo, ApplicationEvent... event) throws Exception {
        var configs = getConfigs();
        var aliPayVm = getRequestVm(configs, vo);
        var pPayVm = dealResponseVm(configs, aliPayVm);
        var checked = checkResponse(pPayVm, aliPayVm);
        if (Boolean.FALSE.equals(checked)) {
            return null;
        }
        if (event != null) {
            publicEvent(getOrderLog(pPayVm, vo), event);
            if (CheckUtil.isNotNullEnum(vo.getRequestType())) {
                redirect(vo);
            }
        }
        return pPayVm.getData();
    }

    /**
     * 拼接orderLog 数据
     */
    private QPayLogsAddVo getOrderLog(PPayVm<String> pPayVm, QOrderInfoVo vo) {
        QPayLogsAddVo data = new QPayLogsAddVo(vo.getQOrderVm().getCode(),
                pPayVm.getPayCode(), vo.getQOrderVm().getPrice(),  PayStatusEnum.PAYING,
                vo.getUserType(), getType(), vo.getServiceBackData(),
                vo.getFrontBackUrl(), vo.getFrontBackData()
        );
        if (CheckUtil.isNotNullEnum(vo.getRequestType())) {
            if (vo.getRequestType() == RedirectTypeEnum.HTTP_REQUEST) {
                data.setServiceBackUrl(vo.getHttpRedirect().getUrl());
            } else if (vo.getRequestType() == RedirectTypeEnum.FEIGN_REQUEST) {
                data.setServiceBackUrl(vo.getFeignRedirect().getUrl());
            }
        }
        return data;
    }
}
